﻿using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace IceDog.DNF.Program.Mvc5.Controllers
{
    /// <summary>
    /// 异步控制器的使用
    /// 约定：在mvc3的版本中提供了定义异步Action的一种方式，即创建XxxAsync()方法和XxxCompleted()两个方法，
    /// XxxCompleted()方法是XxxAsync()方法执行完毕之后的回调方法。ASP.NET并不会以异步的方式执行XxxAsync()方法，
    /// 而是我们在XxxAsync()方法内自行实现异步。MVC4以后的版本我们可以使用Task完成异步操作。
    /// https://www.cnblogs.com/registed/p/5899115.html
    /// </summary>
    public class ColorController : AsyncController
    {
        private string _color;
        public ColorController()
        {
            _color = "black";
        }
        // GET: Color
        public void IndexAsync()
        {
            //异步执行开始标志
            AsyncManager.OutstandingOperations.Increment();
            Task.Factory.StartNew(() =>
            {
                AsyncManager.Parameters.Add("defaultColor", "white");
                AsyncManager.Parameters.Add("currentColor", _color);
                AsyncManager.Parameters.Add("nextColor", "red");
                //异步执行结束标志
                AsyncManager.OutstandingOperations.Decrement();//position 1
            });
            //position 2

            //首先我们把代码中标注1的代码放到//2的位置，再跟踪代码会发现IndexCompleted(string content, int count,Person person)
            //方法中的参数有时会被赋值有时为null，
            //AsyncManager.OutstandingOperations.Decrement(); 标志后台线程执行完毕，此时可以开始执行IndexCompleted方法，
            //如果把它放到2位置处则只是通知IndexAsync方法执行完毕，至于Task.Factory.StartNew中的后台任务不一定执行完毕，
            //所以出现上述情况，因此使用此种方式设计一部Action时我们需要注意
            //AsyncManager.OutstandingOperations.Decrement(); 的位置。
        }

        public ActionResult IndexCompleted(string defaultColor, string currentColor, string nextColor)
        {
            var obj = new
            {
                defaultColor,
                currentColor,
                nextColor
            };
            var serializer = new JavaScriptSerializer();
            var serializedResult = serializer.Serialize(obj);
            return Content(serializedResult);
        }
    }
}